﻿using Mapster;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using RuoVea.ExConfig;
using RuoVea.ExSugar.Option;
using RuoVea.ExSugar.UnitOfWork;
using RuoVea.ExSugar.Util;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace RuoVea.ExSugar;

/// <summary>
/// SqlSugar 启动服务
/// </summary>
public static class SqlsugarSetup
{
    #region 默认DI
    /// <summary>
    /// 添加默认DI
    /// </summary>
    /// <param name="services">服务</param>
    /// <param name="whenUser">whenUser 默认为false true的时候 当有用户cretor的时候将及时过滤</param>
    /// <param name="configId">默认租户</param>
    /// <param name="dataInfoCacheService">sqlsugar缓存</param>
    /// <exception cref="ArgumentNullException"></exception>
    public static void AddSqlsugar(this IServiceCollection services, bool whenUser = false, string configId = null, ICacheService dataInfoCacheService = null)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        List<DbConnectionConfig> dbConnection = (List<DbConnectionConfig>)Appsettings.GetSection("DbConnection:ConnectionConfigs").Get(typeof(List<DbConnectionConfig>));

        List<DbConnectionConfig> connectionConfigs = SugarUtil.ConnectBuilder(dbConnection);
        connectionConfigs.ForEach(config => SugarUtil.SetDbConfig(config, dataInfoCacheService));//配置连接属性

        SqlSugarScope sqlSugar = new(connectionConfigs.Adapt<List<ConnectionConfig>>(), db =>
        {
            connectionConfigs.ForEach(config =>
            {
                if (config.ConfigId == null)
                {
                    var dbProvider = db.GetConnectionScopeWithAttr<SqlSugarScopeProvider>();
                   ;
                    SugarAopUtil.SetDbAop(dbProvider, config, whenUser);//配置Aop
                    //SugarAopUtil.SetDbDiffLog(db.GetConnectionScopeWithAttr<SqlSugarScopeProvider>(), config);
                }
                else
                {
                    var dbProvider = db.GetConnectionScope(config.ConfigId);
                    SugarAopUtil.SetDbAop(dbProvider,config, whenUser);//配置Aop
                    //SugarAopUtil.SetDbDiffLog(dbProvider, config);
                }
            });
        });

        // 初始化数据库表结构及种子数据
        connectionConfigs.ForEach(config => SugarUtil.InitDatabase(sqlSugar, config, configId));
        services.AddSingleton<ISqlSugarClient>(sqlSugar); // 单例注册
        services.AddScoped(typeof(SugarRepository<>)); // 仓储注册
        //工作单元事务
        services.AddMvcCore((options) => options.Filters.Add(typeof(UnitOfWorkFilter)));
    }

    /// <summary>
    /// 注入服务
    /// </summary>
    /// <param name="services"></param>
    /// <param name="assemblys"></param>
    /// <param name="endsWith">Service</param>
    public static void DIService(this IServiceCollection services, List<string> assemblys, string endsWith = "Service")
    {
        foreach (var assembly in assemblys)
        {
            var assemblyService = Assembly.Load(assembly);
            var serviceType = assemblyService.GetTypes().Where(u => u.IsClass && !u.IsAbstract && !u.IsGenericType && u.Name.EndsWith(endsWith)).ToList();

            foreach (var item in serviceType.Where(s => !s.IsInterface))
                services.AddScoped(item);
        }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="services"></param>
    /// <param name="assembly"></param>
    /// <param name="endsWith"></param>
    public static void DIService(this IServiceCollection services, string assembly, string endsWith = "Service")
    {
        var assemblyService = Assembly.Load(assembly);
        var serviceType = assemblyService.GetTypes().Where(u => u.IsClass && !u.IsAbstract && !u.IsGenericType && u.Name.EndsWith(endsWith)).ToList();

        foreach (var item in serviceType.Where(s => !s.IsInterface))
            services.AddScoped(item);
    }
    #endregion
}
